package level.editor.view.base;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import javax.swing.JPanel;

import level.editor.control.main.MainTabbed;
import level.editor.view.Window;
import level.editor.view.desktop.Desktop;
import level.editor.view.group.Item;
import level.editor.view.group.TabbedPane;
import level.editor.view.group.TabbedPane.TabTransferData;

public class CenterPanel extends JPanel
{
	//Called from BasePanel
	public CenterPanel(Desktop desktop)
	{
		super(new BorderLayout());
		this.desktop = desktop;
		init();
	}

	public MainTabbed getMainTabbed()
	{
		return tabbed;
	}
	
	public void initDefaultHandler(Window window)
	{
		tabbed.initDefaultHandler(window);
	}

	private void init()
	{
		add(tabbed = new MainTabbed(desktop), BorderLayout.CENTER);
		initDropSupport();
	}

	private void initDropSupport()
	{
		new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE,
				new DDropTargetListener(), true);
	}

	private Desktop getDesktop()
	{
		return desktop;
	}

	private class DDropTargetListener implements DropTargetListener
	{
		@Override
		public void dragEnter(DropTargetDragEvent e)
		{

			if (isDragAcceptable(e))
			{
				e.acceptDrag(e.getDropAction());
			}
			else
			{
				e.rejectDrag();
			}
		}

		@Override
		public void dragExit(DropTargetEvent e)
		{
			desktop.setRectangle(null, true);
		}

		@Override
		public void dropActionChanged(DropTargetDragEvent e)
		{
		}

		@Override
		public void dragOver(final DropTargetDragEvent e)
		{
			TabTransferData data = getTabTransferData(e);
			TabbedPane source = data.getTabbedPane();
			int sourceIndex = data.getTabIndex();
			if (sourceIndex < 0)
			{
				return;
			}
			Item item = (Item) source.getComponentAt(sourceIndex);
			desktop.setRectangle(
					new Rectangle(e.getLocation(),
							(item.getSize().height >= 600 ? new Dimension(item
									.getSize().width, 600) : item.getSize())),
					true);
		}

		@Override
		public void drop(DropTargetDropEvent a_event)
		{
			if (isDropAcceptable(a_event))
			{
				convertTab(getTabTransferData(a_event), a_event.getLocation());
				a_event.dropComplete(true);
			}
			else
			{
				a_event.dropComplete(false);
			}

			desktop.setRectangle(null, true);
			repaint();
		}

		public boolean isDragAcceptable(DropTargetDragEvent e)
		{
			Transferable t = e.getTransferable();
			if (t == null)
			{
				System.out.println("No transferable");
				return false;
			} // if

			DataFlavor[] flavor = e.getCurrentDataFlavors();
			if (!t.isDataFlavorSupported(flavor[0]))
			{
				System.out.println("No supported data flavor");
				return false;
			} // if

			TabTransferData data = getTabTransferData(e);
			TabbedPane pane = data.getTabbedPane();

			if (pane != null && data.getTabIndex() >= 0)
			{
				return true;
			}

			return false;
		}

		public boolean isDropAcceptable(DropTargetDropEvent e)
		{
			Transferable t = e.getTransferable();
			if (t == null)
			{
				return false;
			} // if

			DataFlavor[] flavor = e.getCurrentDataFlavors();
			if (!t.isDataFlavorSupported(flavor[0]))
			{
				return false;
			} // if

			TabTransferData data = getTabTransferData(e);
			TabbedPane pane = data.getTabbedPane();

			if (pane != null && data.getTabIndex() >= 0)
			{
				return true;
			}

			return false;
		}
	}

	private void convertTab(TabTransferData tabTransferData, Point point)
	{
		TabbedPane source = tabTransferData.getTabbedPane();
		int sourceIndex = tabTransferData.getTabIndex();
		if (sourceIndex < 0)
		{
			return;
		}
		Item item = (Item) source.getComponentAt(sourceIndex);
		// System.out.println(item);
		source.safeRemove(sourceIndex);
		item.setSize((item.getSize().height >= 500 ? new Dimension(item
				.getSize().width, 500) : item.getSize()));
		getDesktop()
				.addFrameFromTab(item, new Rectangle(point, item.getSize()));
		source.removeCheck();
	}

	private TabTransferData getTabTransferData(DropTargetDropEvent a_event)
	{
		try
		{
			TabTransferData data = (TabTransferData) a_event.getTransferable()
					.getTransferData(FLAVOR);
			return data;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		return null;
	}

	private TabTransferData getTabTransferData(DropTargetDragEvent a_event)
	{
		try
		{
			TabTransferData data = (TabTransferData) a_event.getTransferable()
					.getTransferData(FLAVOR);
			return data;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		return null;
	}

	private static final String NAME = "TabTransferData";
	private final DataFlavor FLAVOR = new DataFlavor(
			DataFlavor.javaJVMLocalObjectMimeType, NAME);
	private Desktop desktop;
	private MainTabbed tabbed;
}
